#include <iostream>
#include <string>

#include <boost/test/unit_test.hpp>

#include <JuegoLib/EventType.h>
#include <JuegoLib/IEventData.h>
#include <JuegoLib/EvtData.h>
#include <JuegoLib/Event.h>
#include <JuegoLib/IEventListener.h>
#include <JuegoLib/IEventManager.h>
#include <JuegoLib/EventManager.h>

BOOST_AUTO_TEST_SUITE ( Event_System_Tests )


BOOST_AUTO_TEST_CASE( EventTypeClass )
{
	EventType evt1( "TestEv" );
	EventType evt2( "TestEv" );
	EventType evt3( "TsetEv" );

	BOOST_CHECK( evt1.GetIdent() == evt2.GetIdent() );
	BOOST_CHECK( evt3.GetIdent() != evt1.GetIdent() );
	BOOST_CHECK( strcmp(evt1.GetIdentStr(), "TestEv") == 0 );

	BOOST_CHECK( evt1 == evt2 );

	BOOST_CHECK( ! (evt1 < evt2) );
}

BOOST_AUTO_TEST_CASE( IEventDataClass )
{
	IEventData::Ptr p(new IEventData);
}

BOOST_AUTO_TEST_CASE( EvtDataClass )
{
	EvtData<int> evd1( 5 );
	BOOST_CHECK( evd1.GetValue() == 5 );

	EvtData<std::string> evd2 (std::string("str"));
	BOOST_CHECK( evd2.GetValue() == "str" );
}


BOOST_AUTO_TEST_CASE( EventClass )
{
	EventType type("test_event");

	IEventData::Ptr evd1(new EvtData<int>(5));
	Event::Ptr ptr(new Event("test_event", evd1));

	BOOST_CHECK( type == ptr->GetType() );

	IEventData::Ptr ep1 = ptr->GetData();
	EvtData<int> * ep2 = ptr->GetDataPtr< EvtData<int> >();

	BOOST_CHECK( ep2->GetValue() == 5 );
}

class TestEventListener : public IEventListener
{
public:

	int mTestVal;

	TestEventListener() : mTestVal(0) {}

	virtual char const * GetName() { return "TestEventListener"; }

	virtual bool HandleEvent( Event const & ev )
	{
		BOOST_CHECK(ev.GetType() == EventType("TestEvent"));
		mTestVal++;
		return true;
	}
};

BOOST_AUTO_TEST_CASE( ListenersAndManagerClasses )
{

	EventManager * evMgr = new EventManager("evManager");
	IEventManager::Ptr evMgrPtr(evMgr);

	TestEventListener * testListener = new TestEventListener();
	IEventListener::Ptr listener(testListener);

	bool b = evMgr->AddListener(listener, EventType("TestEvent"));

	BOOST_CHECK (b == true);

	evMgr->Update();

	BOOST_CHECK( testListener->mTestVal == 0 );

	evMgr->QueueEvent( Event::Ptr(new Event("TestEvent")) );

	evMgr->Trigger( *Event::Ptr(new Event("TestEvent")) );

	BOOST_CHECK( testListener->mTestVal == 1 );

	evMgr->QueueEvent( Event::Ptr(new Event("TestEvent")) );

	evMgr->Update();

	BOOST_CHECK( testListener->mTestVal == 3 );
	 
}


BOOST_AUTO_TEST_SUITE_END()